var isIE = (document.all) ? true : false;

var dobj = function(id) {
    return "string" == typeof id ? document.getElementById(id) : id;
};

var Class = {
    create: function() {
        return function() { this.initialize.apply(this, arguments); }
    }
}

var Extend = function(destination, source) {
    for (var property in source) {
        destination[property] = source[property];
    }
}

var Bind = function(object, fun) {
    return function() {
        return fun.apply(object, arguments);
    }
}
var BindAsEventListener = function(object, fun) {
    var args = Array.prototype.slice.call(arguments).slice(2);
    return function(event) {
        return fun.apply(object, [event || window.event].concat(args));
    }
}

var CurrentStyle = function(element) {
    return element.currentStyle || document.defaultView.getComputedStyle(element, null);
}

function addEventHandler(oTarget, sEventType, fnHandler) {
    if (oTarget.addEventListener) {
        oTarget.addEventListener(sEventType, fnHandler, false);
    } else if (oTarget.attachEvent) {
        oTarget.attachEvent("on" + sEventType, fnHandler);
    } else {
        oTarget["on" + sEventType] = fnHandler;
    }
};

function removeEventHandler(oTarget, sEventType, fnHandler) {
    if (oTarget.removeEventListener) {
        oTarget.removeEventListener(sEventType, fnHandler, false);
    } else if (oTarget.detachEvent) {
        oTarget.detachEvent("on" + sEventType, fnHandler);
    } else {
        oTarget["on" + sEventType] = null;
    }
};
//缩放程序
var Resize = Class.create();
Resize.prototype = {
    //缩放对象
    initialize: function(obj, options) {
        this._obj = obj.get(0); //缩放对象

        this._styleWidth = this._styleHeight = this._styleLeft = this._styleTop = 0; //样式参数
        this._sideRight = this._sideDown = this._sideLeft = this._sideUp = 0; //坐标参数
        this._fixLeft = this._fixTop = 0; //定位参数
        this._scaleLeft = this._scaleTop = 0; //定位坐标

        this._mxSet = function() {}; //范围设置程序
        this._mxRightWidth = this._mxDownHeight = this._mxUpHeight = this._mxLeftWidth = 0; //范围参数
        this._mxScaleWidth = this._mxScaleHeight = 0; //比例范围参数

        this._fun = function() {}; //缩放执行程序

        //获取边框宽度
        var _style = CurrentStyle(this._obj);
        this._borderX = (parseInt(_style.borderLeftWidth) || 0) + (parseInt(_style.borderRightWidth) || 0);
        this._borderY = (parseInt(_style.borderTopWidth) || 0) + (parseInt(_style.borderBottomWidth) || 0);
        //事件对象(用于绑定移除事件)
        this._fR = BindAsEventListener(this, this.Resize);
        this._fS = Bind(this, this.Stop);

        this.SetOptions(options);
        //范围限制
        this.Max = !!this.options.Max;
        this._mxContainer = $(this.options.mxContainer).get(0) || null;
        this.mxLeft = Math.round(this.options.mxLeft);
        this.mxRight = Math.round(this.options.mxRight);
        this.mxTop = Math.round(this.options.mxTop);
        this.mxBottom = Math.round(this.options.mxBottom);
        //宽高限制
        this.Min = !!this.options.Min;
        this.minWidth = Math.round(this.options.minWidth);
        this.minHeight = Math.round(this.options.minHeight);
        //按比例缩放
        this.Scale = !!this.options.Scale;
        this.Ratio = Math.max(this.options.Ratio, 0);

        this.onResize = this.options.onResize;

        this._obj.style.position = "absolute";
        !this._mxContainer || CurrentStyle(this._mxContainer).position == "relative" || (this._mxContainer.style.position = "relative");
    },
    //设置默认属性
    SetOptions: function(options) {
        this.options = { //默认值
            Max: false, //是否设置范围限制(为true时下面mx参数有用)
            mxContainer: "", //指定限制在容器内
            mxLeft: 0, //左边限制
            mxRight: 9999, //右边限制
            mxTop: 0, //上边限制
            mxBottom: 9999, //下边限制
            Min: false, //是否最小宽高限制(为true时下面min参数有用)
            minWidth: 50, //最小宽度
            minHeight: 50, //最小高度
            Scale: false, //是否按比例缩放
            Ratio: 0, //缩放比例(宽/高)
            onResize: function() {} //缩放时执行
        };
        Extend(this.options, options || {});
    },
    //设置触发对象
    Set: function(resize, side) {
        var fun;
        if (!resize) return;
        //根据方向设置
        switch (side.toLowerCase()) {
            case "up":
                fun = this.Up;
                break;
            case "down":
                fun = this.Down;
                break;
            case "left":
                fun = this.Left;
                break;
            case "right":
                fun = this.Right;
                break;
            case "left-up":
                fun = this.LeftUp;
                break;
            case "right-up":
                fun = this.RightUp;
                break;
            case "left-down":
                fun = this.LeftDown;
                break;
            case "right-down":
            default:
                fun = this.RightDown;
        };
        //设置触发对象
        addEventHandler(resize.get(0), "mousedown", BindAsEventListener(this, this.Start, fun));
    },
    //准备缩放
    Start: function(e, fun, touch) {

        //防止冒泡(跟拖放配合时设置)
        e.stopPropagation ? e.stopPropagation() : (e.cancelBubble = true);
        //设置执行程序
        this._fun = fun;
        //样式参数值
        this._styleWidth = this._obj.clientWidth;
        this._styleHeight = this._obj.clientHeight;
        this._styleLeft = this._obj.offsetLeft;
        this._styleTop = this._obj.offsetTop;
        //四条边定位坐标
        this._sideLeft = e.clientX - this._styleWidth;
        this._sideRight = e.clientX + this._styleWidth;
        this._sideUp = e.clientY - this._styleHeight;
        this._sideDown = e.clientY + this._styleHeight;
        //top和left定位参数
        this._fixLeft = this._styleLeft + this._styleWidth;
        this._fixTop = this._styleTop + this._styleHeight;
        //缩放比例
        if (this.Scale) {
            //设置比例
            this.Ratio = Math.max(this.Ratio, 0) || this._styleWidth / this._styleHeight;
            //left和top的定位坐标
            this._scaleLeft = this._styleLeft + this._styleWidth / 2;
            this._scaleTop = this._styleTop + this._styleHeight / 2;
        };
        //范围限制
        if (this.Max) {
            //设置范围参数
            var mxLeft = this.mxLeft,
                mxRight = this.mxRight,
                mxTop = this.mxTop,
                mxBottom = this.mxBottom;
            //如果设置了容器，再修正范围参数
            if (!!this._mxContainer) {
                mxLeft = Math.max(mxLeft, 0);
                mxTop = Math.max(mxTop, 0);
                mxRight = Math.min(mxRight, this._mxContainer.clientWidth);
                mxBottom = Math.min(mxBottom, this._mxContainer.clientHeight);
            };
            //根据最小值再修正
            mxRight = Math.max(mxRight, mxLeft + (this.Min ? this.minWidth : 0) + this._borderX);
            mxBottom = Math.max(mxBottom, mxTop + (this.Min ? this.minHeight : 0) + this._borderY);
            //由于转向时要重新设置所以写成function形式
            this._mxSet = function() {
                this._mxRightWidth = mxRight - this._styleLeft - this._borderX;
                this._mxDownHeight = mxBottom - this._styleTop - this._borderY;
                this._mxUpHeight = Math.max(this._fixTop - mxTop, this.Min ? this.minHeight : 0);
                this._mxLeftWidth = Math.max(this._fixLeft - mxLeft, this.Min ? this.minWidth : 0);
            };
            this._mxSet();
            //有缩放比例下的范围限制
            if (this.Scale) {
                this._mxScaleWidth = Math.min(this._scaleLeft - mxLeft, mxRight - this._scaleLeft - this._borderX) * 2;
                this._mxScaleHeight = Math.min(this._scaleTop - mxTop, mxBottom - this._scaleTop - this._borderY) * 2;
            };
        };
        //mousemove时缩放 mouseup时停止
        addEventHandler(document, "mousemove", this._fR);
        addEventHandler(document, "mouseup", this._fS);
        if (isIE) {
            addEventHandler(this._obj, "losecapture", this._fS);
            this._obj.setCapture();
        } else {
            addEventHandler(window, "blur", this._fS);
            e.preventDefault();
        };
    },
    //缩放
    Resize: function(e) {
        //清除选择
        window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
        //执行缩放程序
        this._fun(e);
        //设置样式，变量必须大于等于0否则ie出错
        with(this._obj.style) {
                width = this._styleWidth + "px";
                height = this._styleHeight + "px";
                top = this._styleTop + "px";
                left = this._styleLeft + "px";
            }
            //附加程序
        this.onResize();
    },
    //缩放程序
    //上
    Up: function(e) {
        this.RepairY(this._sideDown - e.clientY, this._mxUpHeight);
        this.RepairTop();
        this.TurnDown(this.Down);
    },
    //下
    Down: function(e) {
        this.RepairY(e.clientY - this._sideUp, this._mxDownHeight);
        this.TurnUp(this.Up);
    },
    //右
    Right: function(e) {
        this.RepairX(e.clientX - this._sideLeft, this._mxRightWidth);
        this.TurnLeft(this.Left);
    },
    //左
    Left: function(e) {
        this.RepairX(this._sideRight - e.clientX, this._mxLeftWidth);
        this.RepairLeft();
        this.TurnRight(this.Right);
    },
    //右下
    RightDown: function(e) {
        this.RepairAngle(
            e.clientX - this._sideLeft, this._mxRightWidth,
            e.clientY - this._sideUp, this._mxDownHeight
        );
        this.TurnLeft(this.LeftDown) || this.Scale || this.TurnUp(this.RightUp);
    },
    //右上
    RightUp: function(e) {
        this.RepairAngle(
            e.clientX - this._sideLeft, this._mxRightWidth,
            this._sideDown - e.clientY, this._mxUpHeight
        );
        this.RepairTop();
        this.TurnLeft(this.LeftUp) || this.Scale || this.TurnDown(this.RightDown);
    },
    //左下
    LeftDown: function(e) {
        this.RepairAngle(
            this._sideRight - e.clientX, this._mxLeftWidth,
            e.clientY - this._sideUp, this._mxDownHeight
        );
        this.RepairLeft();
        this.TurnRight(this.RightDown) || this.Scale || this.TurnUp(this.LeftUp);
    },
    //左上
    LeftUp: function(e) {
        this.RepairAngle(
            this._sideRight - e.clientX, this._mxLeftWidth,
            this._sideDown - e.clientY, this._mxUpHeight
        );
        this.RepairTop();
        this.RepairLeft();
        this.TurnRight(this.RightUp) || this.Scale || this.TurnDown(this.LeftDown);
    },
    //修正程序
    //水平方向
    RepairX: function(iWidth, mxWidth) {
        iWidth = this.RepairWidth(iWidth, mxWidth);
        if (this.Scale) {
            var iHeight = this.RepairScaleHeight(iWidth);
            if (this.Max && iHeight > this._mxScaleHeight) {
                iHeight = this._mxScaleHeight;
                iWidth = this.RepairScaleWidth(iHeight);
            } else if (this.Min && iHeight < this.minHeight) {
                var tWidth = this.RepairScaleWidth(this.minHeight);
                if (tWidth < mxWidth) {
                    iHeight = this.minHeight;
                    iWidth = tWidth;
                }
            }
            this._styleHeight = iHeight;
            this._styleTop = this._scaleTop - iHeight / 2;
        }
        this._styleWidth = iWidth;
    },
    //垂直方向
    RepairY: function(iHeight, mxHeight) {
        iHeight = this.RepairHeight(iHeight, mxHeight);
        if (this.Scale) {
            var iWidth = this.RepairScaleWidth(iHeight);
            if (this.Max && iWidth > this._mxScaleWidth) {
                iWidth = this._mxScaleWidth;
                iHeight = this.RepairScaleHeight(iWidth);
            } else if (this.Min && iWidth < this.minWidth) {
                var tHeight = this.RepairScaleHeight(this.minWidth);
                if (tHeight < mxHeight) {
                    iWidth = this.minWidth;
                    iHeight = tHeight;
                }
            }
            this._styleWidth = iWidth;
            this._styleLeft = this._scaleLeft - iWidth / 2;
        }
        this._styleHeight = iHeight;
    },
    //对角方向
    RepairAngle: function(iWidth, mxWidth, iHeight, mxHeight) {
        iWidth = this.RepairWidth(iWidth, mxWidth);
        if (this.Scale) {
            iHeight = this.RepairScaleHeight(iWidth);
            if (this.Max && iHeight > mxHeight) {
                iHeight = mxHeight;
                iWidth = this.RepairScaleWidth(iHeight);
            } else if (this.Min && iHeight < this.minHeight) {
                var tWidth = this.RepairScaleWidth(this.minHeight);
                if (tWidth < mxWidth) {
                    iHeight = this.minHeight;
                    iWidth = tWidth;
                }
            }
        } else {
            iHeight = this.RepairHeight(iHeight, mxHeight);
        }
        this._styleWidth = iWidth;
        this._styleHeight = iHeight;
    },
    //top
    RepairTop: function() {
        this._styleTop = this._fixTop - this._styleHeight;
    },
    //left
    RepairLeft: function() {
        this._styleLeft = this._fixLeft - this._styleWidth;
    },
    //height
    RepairHeight: function(iHeight, mxHeight) {
        iHeight = Math.min(this.Max ? mxHeight : iHeight, iHeight);
        iHeight = Math.max(this.Min ? this.minHeight : iHeight, iHeight, 0);
        return iHeight;
    },
    //width
    RepairWidth: function(iWidth, mxWidth) {
        iWidth = Math.min(this.Max ? mxWidth : iWidth, iWidth);
        iWidth = Math.max(this.Min ? this.minWidth : iWidth, iWidth, 0);
        return iWidth;
    },
    //比例高度
    RepairScaleHeight: function(iWidth) {
        return Math.max(Math.round((iWidth + this._borderX) / this.Ratio - this._borderY), 0);
    },
    //比例宽度
    RepairScaleWidth: function(iHeight) {
        return Math.max(Math.round((iHeight + this._borderY) * this.Ratio - this._borderX), 0);
    },
    //转向程序
    //转右
    TurnRight: function(fun) {
        if (!(this.Min || this._styleWidth)) {
            this._fun = fun;
            this._sideLeft = this._sideRight;
            this.Max && this._mxSet();
            return true;
        }
    },
    //转左
    TurnLeft: function(fun) {
        if (!(this.Min || this._styleWidth)) {
            this._fun = fun;
            this._sideRight = this._sideLeft;
            this._fixLeft = this._styleLeft;
            this.Max && this._mxSet();
            return true;
        }
    },
    //转上
    TurnUp: function(fun) {
        if (!(this.Min || this._styleHeight)) {
            this._fun = fun;
            this._sideDown = this._sideUp;
            this._fixTop = this._styleTop;
            this.Max && this._mxSet();
            return true;
        }
    },
    //转下
    TurnDown: function(fun) {
        if (!(this.Min || this._styleHeight)) {
            this._fun = fun;
            this._sideUp = this._sideDown;
            this.Max && this._mxSet();
            return true;
        }
    },
    //停止缩放
    Stop: function() {
        removeEventHandler(document, "mousemove", this._fR);
        removeEventHandler(document, "mouseup", this._fS);
        if (isIE) {
            removeEventHandler(this._obj, "losecapture", this._fS);
            this._obj.releaseCapture();
        } else {
            removeEventHandler(window, "blur", this._fS);
        }
    }
};

//拖放程序
var Drag = Class.create();
Drag.prototype = {
    //拖放对象
    initialize: function(drag, options) {
        this.Drag = drag.get(0); //拖放对象
        this._x = this._y = 0; //记录鼠标相对拖放对象的位置
        this._marginLeft = this._marginTop = 0; //记录margin
        //事件对象(用于绑定移除事件)
        this._fM = BindAsEventListener(this, this.Move);
        this._fS = Bind(this, this.Stop);

        this.SetOptions(options);

        this.Limit = !!this.options.Limit;
        this.mxLeft = parseInt(this.options.mxLeft);
        this.mxRight = parseInt(this.options.mxRight);
        this.mxTop = parseInt(this.options.mxTop);
        this.mxBottom = parseInt(this.options.mxBottom);

        this.LockX = !!this.options.LockX;
        this.LockY = !!this.options.LockY;
        this.Lock = !!this.options.Lock;

        this.onStart = this.options.onStart;
        this.onMove = this.options.onMove;
        this.onStop = this.options.onStop;

        this._Handle = $(this.options.Handle).get(0) || this.Drag;
        this._mxContainer = $(this.options.mxContainer).get(0) || null;

        this.Drag.style.position = "absolute";
        //透明
        if (isIE && !!this.options.Transparent) {
            //填充拖放对象
            with(this._Handle.appendChild(document.createElement("div")).style) {
                width = height = "100%";
                backgroundColor = "#fff";
                filter = "alpha(opacity:0)";
                fontSize = 0;
            }
        }
        //修正范围
        this.Repair();
        addEventHandler(this._Handle, "mousedown", BindAsEventListener(this, this.Start));
    },
    //设置默认属性
    SetOptions: function(options) {
        this.options = { //默认值
            Handle: "", //设置触发对象（不设置则使用拖放对象）
            Limit: false, //是否设置范围限制(为true时下面参数有用,可以是负数)
            mxLeft: 0, //左边限制
            mxRight: 9999, //右边限制
            mxTop: 0, //上边限制
            mxBottom: 9999, //下边限制
            mxContainer: "", //指定限制在容器内
            LockX: false, //是否锁定水平方向拖放
            LockY: false, //是否锁定垂直方向拖放
            Lock: false, //是否锁定
            Transparent: false, //是否透明
            onStart: function() {}, //开始移动时执行
            onMove: function() {}, //移动时执行
            onStop: function() {} //结束移动时执行
        };
        Extend(this.options, options || {});
    },
    //准备拖动
    Start: function(oEvent) {
        if (this.Lock) { return; }
        this.Repair();
        //记录鼠标相对拖放对象的位置
        this._x = oEvent.clientX - this.Drag.offsetLeft;
        this._y = oEvent.clientY - this.Drag.offsetTop;
        //记录margin
        this._marginLeft = parseInt(CurrentStyle(this.Drag).marginLeft) || 0;
        this._marginTop = parseInt(CurrentStyle(this.Drag).marginTop) || 0;
        //mousemove时移动 mouseup时停止
        addEventHandler(document, "mousemove", this._fM);
        addEventHandler(document, "mouseup", this._fS);
        if (isIE) {
            //焦点丢失
            addEventHandler(this._Handle, "losecapture", this._fS);
            //设置鼠标捕获
            this._Handle.setCapture();
        } else {
            //焦点丢失
            addEventHandler(window, "blur", this._fS);
            //阻止默认动作
            oEvent.preventDefault();
        };
        //附加程序
        this.onStart();
    },
    //修正范围
    Repair: function() {
        if (this.Limit) {
            //修正错误范围参数
            this.mxRight = Math.max(this.mxRight, this.mxLeft + this.Drag.offsetWidth);
            this.mxBottom = Math.max(this.mxBottom, this.mxTop + this.Drag.offsetHeight);
            //如果有容器必须设置position为relative或absolute来相对或绝对定位，并在获取offset之前设置
            !this._mxContainer || CurrentStyle(this._mxContainer).position == "relative" || CurrentStyle(this._mxContainer).position == "absolute" || (this._mxContainer.style.position = "relative");
        }
    },
    //拖动
    Move: function(oEvent) {
        //判断是否锁定
        if (this.Lock) { this.Stop(); return; };
        //清除选择
        window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
        //设置移动参数
        var iLeft = oEvent.clientX - this._x,
            iTop = oEvent.clientY - this._y;
        //设置范围限制
        if (this.Limit) {
            //设置范围参数
            var mxLeft = this.mxLeft,
                mxRight = this.mxRight,
                mxTop = this.mxTop,
                mxBottom = this.mxBottom;
            //如果设置了容器，再修正范围参数
            if (!!this._mxContainer) {
                mxLeft = Math.max(mxLeft, 0);
                mxTop = Math.max(mxTop, 0);
                mxRight = Math.min(mxRight, this._mxContainer.clientWidth);
                mxBottom = Math.min(mxBottom, this._mxContainer.clientHeight);
            };
            //修正移动参数
            iLeft = Math.max(Math.min(iLeft, mxRight - this.Drag.offsetWidth), mxLeft);
            iTop = Math.max(Math.min(iTop, mxBottom - this.Drag.offsetHeight), mxTop);
        }
        //设置位置，并修正margin
        if (!this.LockX) { this.Drag.style.left = iLeft - this._marginLeft + "px"; }
        if (!this.LockY) { this.Drag.style.top = iTop - this._marginTop + "px"; }
        //附加程序
        this.onMove();
    },
    //停止拖动
    Stop: function() {
        //移除事件
        removeEventHandler(document, "mousemove", this._fM);
        removeEventHandler(document, "mouseup", this._fS);
        if (isIE) {
            removeEventHandler(this._Handle, "losecapture", this._fS);
            this._Handle.releaseCapture();
        } else {
            removeEventHandler(window, "blur", this._fS);
        };
        //附加程序
        this.onStop();
    }
};

function dragEvent(obj, dragCall, sizeCall) {
    obj.append('<div class="corner dRightDown"></div>');
    obj.append('<div class="corner dLeftDown"></div>');
    obj.append('<div class="corner dRightUp"></div>');
    obj.append('<div class="corner dLeftUp"></div>');
    obj.append('<div class="corner dRight"></div>');
    obj.append('<div class="corner dLeft"></div>');
    obj.append('<div class="corner rUp"></div>');
    obj.append('<div class="corner rDown"></div>');
    var posterrs = new Resize(obj, {
        Max: true,
        mxContainer: "#view-box",
        onResize: sizeCall ? sizeCall : function() {}
    });
    posterrs.Set($(".dRightDown", obj), "right-down");
    posterrs.Set($(".dLeftDown", obj), "left-down");
    posterrs.Set($(".dRightUp", obj), "right-up");
    posterrs.Set($(".dLeftUp", obj), "left-up");
    posterrs.Set($(".dRight", obj), "right");
    posterrs.Set($(".dLeft", obj), "left");
    posterrs.Set($(".rUp", obj), "up");
    posterrs.Set($(".rDown", obj), "down");
    posterrs.Scale = true;

    new Drag(obj, {
        Limit: true,
        mxContainer: "#view-box",
        onStop: dragCall ? dragCall : function() {}
    });
}